﻿////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// <copyright>Copyright 2008-2011 Andreas Huber Doenni</copyright>
// Distributed under the GNU General Public License version 2 (GPLv2).
// See accompanying file License.txt or copy at http://phuse.codeplex.com/license.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace Phuse.IO
{
    using System;

    /// <summary>Provides a thin wrapper for a buffer that is emptied by calling the provided callbacks.</summary>
    /// <remarks>
    /// <para>The fields in this class and its base are not encapsulated properly for performance reasons. See
    /// <see cref="ReadBuffer"/> for more information.</para>
    /// </remarks>
    internal sealed class WriteBuffer : Buffer
    {
        private readonly Action<byte[], int, int> writeCallback;
        private readonly Action flushCallback;

        /// <summary>Initializes a new instance of the <see cref="WriteBuffer"/> class.</summary>
        /// <param name="writeCallback">The method that is called when the buffer needs to be emptied.</param>
        /// <param name="flushCallback">The method that is called when the buffer has been emptied successfully.</param>
        /// <param name="bufferSize">The size of the internal buffer in bytes.</param>
        internal WriteBuffer(Action<byte[], int, int> writeCallback, Action flushCallback, int bufferSize) :
            base(bufferSize)
        {
            this.writeCallback = writeCallback;
            this.flushCallback = flushCallback;
        }

        /// <summary>Empties the contents of the buffer by calling the callbacks specified at construction.</summary>
        /// <returns>Always <c>true</c>.</returns>
        /// <remarks>After calling this function, <see cref="Buffer.Count"/> equals 0.</remarks>
        internal bool Flush()
        {
            this.writeCallback(this.GetBuffer(), 0, this.Count);
            this.Count = 0;
            this.flushCallback();
            return true;
        }
    }
}
